﻿using System;
using System.Collections.Generic;

namespace CoreRay
{
    //-----------------------------------------------------------------------------------------
    /// <summary>
    /// Manages the generation of samples for a given render region.
    /// </summary>
    //-----------------------------------------------------------------------------------------

    public abstract class Sampler
    {
        //-----------------------------------------------------------------------------------------
        /// <summary>
        /// Initializes a new instance of the <see cref="Sampler"/> class.
        /// </summary>
        /// <param name="renderRegion">The render region used for sampling.</param>
        /// <param name="samplesPerPixel">The number of samples per pixel.</param>
        //-----------------------------------------------------------------------------------------

        protected Sampler(RenderRegion renderRegion, int samplesPerPixel)
        {
            this.RenderRegion = renderRegion;
            this.SamplesPerPixel = samplesPerPixel;
        }


        //-----------------------------------------------------------------------------------------
        /// <summary>
        /// Gets the render region used for sampling.
        /// </summary>
        /// <value>The render region used for sampling.</value>
        //-----------------------------------------------------------------------------------------

        public RenderRegion RenderRegion
        {
            get;
            private set;
        }


        //-----------------------------------------------------------------------------------------
        /// <summary>
        /// Gets the samples per pixel.
        /// </summary>
        /// <value>The samples per pixel.</value>
        //-----------------------------------------------------------------------------------------

        public int SamplesPerPixel
        {
            get;
            private set;
        }


        //-----------------------------------------------------------------------------------------
        /// <summary>
        /// Gets the total samples that will be generated by the sampler.
        /// </summary>
        /// <value>The total samples.</value>
        //-----------------------------------------------------------------------------------------

        public int TotalSamples
        {
            get
            {
                return this.SamplesPerPixel * (this.RenderRegion.Width - this.RenderRegion.PositionX) * (this.RenderRegion.Height - this.RenderRegion.PositionY);
            }
        }


        //-----------------------------------------------------------------------------------------
        /// <summary>
        /// Generates the samples for the given render region.
        /// </summary>
        /// <returns>An enumeration of the samples generated by the sampler.</returns>
        //-----------------------------------------------------------------------------------------

        public IEnumerable<Sample> GenerateSamples()
        {
            Sample sample = this.GetNextSample();

            while(sample != null)
            {
                yield return sample;

                sample = this.GetNextSample();
            }
        }


        //-----------------------------------------------------------------------------------------
        /// <summary>
        /// Returns the next sample. This method must be overrided by samplers.
        /// </summary>
        /// <returns>The next sample or null if all the samples have been generated.</returns>
        //-----------------------------------------------------------------------------------------

        protected abstract Sample GetNextSample();
    }
}
